package sqlite_conf_table

import (
	"database/sql"
	"github.com/sirupsen/logrus"
	"go-iot-gateway/internal/conf_table/define"
	"strconv"
	"strings"
)

/*
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`tag_descYcxmkt` varchar(10) DEFAULT NULL,
`tag_reserve` int(2) DEFAULT NULL ,
`tag_id` varchar(10) DEFAULT NULL,
`tag_name` varchar(64) DEFAULT NULL,
`tag_desc` varchar(100) DEFAULT NULL,
`tag_type` int(2) DEFAULT NULL,
`tag_RW` int(2) DEFAULT NULL,
`tag_init` float DEFAULT NULL,
`tag_K` float DEFAULT NULL,
`tag_B` float DEFAULT NULL,
`collect_type` int(10) DEFAULT NULL,
`obj_addr` varchar(50) DEFAULT NULL,
`assist_param` varchar(50) DEFAULT NULL,
`tag_group` varchar(10) DEFAULT NULL,
`data_type` int(2) DEFAULT NULL,
`data_format` int(2) DEFAULT NULL,
`enable_trans` int(2) DEFAULT NULL,
`org_read_value` int(10) DEFAULT NULL,
`trans_value` int(10) DEFAULT NULL,
`enable_bit` int(2) DEFAULT NULL,
`start_bit` int(2) DEFAULT NULL,
`end_bit` int(2) DEFAULT NULL,
`dev_id` varchar(10) DEFAULT NULL,
`enable_alarm` int(2) DEFAULT NULL,
`hh_enable_alarm` int(2) DEFAULT NULL,
`h_enable_alarm` int(2) DEFAULT NULL,
`l_enable_alarm` int(2) DEFAULT NULL,
`ll_enable_alarm` int(2) DEFAULT NULL,
`hh_alarm_limit` float DEFAULT NULL,
`h_alarm_limit` float DEFAULT NULL,
`l_alarm_limit` float DEFAULT NULL,
`ll_alarm_limit` float DEFAULT NULL,
`hh_alarm_msg` varchar(100) DEFAULT NULL,
`h_alarm_msg` varchar(100) DEFAULT NULL,
`l_alarm_msg` varchar(100) DEFAULT NULL,
`ll_alarm_msg` varchar(100) DEFAULT NULL,
`alarm_dead_area` float DEFAULT NULL,
`kg_change_mode` int(2) DEFAULT NULL,
`kg_alarm_msg` varchar(100) DEFAULT NULL,
`alarm_level` int(2) DEFAULT NULL,
`enable_his_save` int(2) DEFAULT NULL,
`his_save_type` int(2) DEFAULT NULL,
`his_save_interval` int(10) DEFAULT NULL,
`his_comp_perc` float DEFAULT NULL,
`is_upload` int(2) DEFAULT NULL,
`pv_flag` int(10) DEFAULT NULL,
`tag_source` int(2) DEFAULT NULL,
`tag_unit` varchar(50) DEFAULT NULL,
`rev2` varchar(50) DEFAULT NULL,
`rev3` varchar(50) DEFAULT NULL,
`rev4` varchar(50) DEFAULT NULL,
`ori_tag_id` int(10) DEFAULT NULL,
`tag_id_f` int(10) DEFAULT NULL,
`tag_id_h` int(10) DEFAULT NULL,
`w_value_f` varchar(50) DEFAULT NULL,
`w_value_h` varchar(50) DEFAULT NULL
*/

var tbTagInfoColumns = []string{"id",
	"tag_descYcxmkt",
	"tag_reserve",
	"tag_id",
	"tag_name",
	"tag_desc",
	"tag_type",
	"tag_RW",
	"tag_init",
	"tag_K",
	"tag_B",
	"collect_type",
	"obj_addr",
	"assist_param",
	"tag_group",
	"data_type",
	"data_format",
	"enable_trans",
	"org_read_value",
	"trans_value",
	"enable_bit",
	"start_bit",
	"end_bit",
	"dev_id",
	"enable_alarm",
	"hh_enable_alarm",
	"h_enable_alarm",
	"l_enable_alarm",
	"ll_enable_alarm",
	"hh_alarm_limit",
	"h_alarm_limit",
	"l_alarm_limit",
	"ll_alarm_limit",
	"hh_alarm_msg",
	"h_alarm_msg",
	"l_alarm_msg",
	"ll_alarm_msg",
	"alarm_dead_area",
	"kg_change_mode",
	"kg_alarm_msg",
	"alarm_level",
	"enable_his_save",
	"his_save_type",
	"his_save_interval",
	"his_comp_perc",
	"is_upload",
	"pv_flag",
	"tag_source",
	"tag_unit",
	"rev2",
	"rev3",
	"rev4",
	"ori_tag_id",
	"tag_id_f",
	"tag_id_h",
	"w_value_f",
	"w_value_h"}

type tagInfoEntity struct {
	id                *int
	tag_descYcxmkt    *string
	tag_reserve       *int
	tag_id            *string
	tag_name          *string
	tag_desc          *string
	tag_type          *int
	tag_RW            *int
	tag_init          *float32
	tag_K             *float32
	tag_B             *float32
	collect_type      *int
	obj_addr          *string
	assist_param      *string
	tag_group         *string
	data_type         *int
	data_format       *int
	enable_trans      *int
	org_read_value    *int
	trans_value       *int
	enable_bit        *int
	start_bit         *uint32
	end_bit           *uint32
	dev_id            *string
	enable_alarm      *int
	hh_enable_alarm   *int
	h_enable_alarm    *int
	l_enable_alarm    *int
	ll_enable_alarm   *int
	hh_alarm_limit    *int
	h_alarm_limit     *float32
	l_alarm_limit     *float32
	ll_alarm_limit    *float32
	hh_alarm_msg      *string
	h_alarm_msg       *string
	l_alarm_msg       *string
	ll_alarm_msg      *string
	alarm_dead_area   *float32
	kg_change_mode    *int
	kg_alarm_msg      *string
	alarm_level       *int
	enable_his_save   *int
	his_save_type     *int
	his_save_interval *int
	his_comp_perc     *float32
	is_upload         *int
	pv_flag           *int
	tag_source        *int
	tag_unit          *string
	rev2              *string
	rev3              *string
	rev4              *string
	ori_tag_id        *int
	tag_id_f          *int
	tag_id_h          *int
	w_value_f         *string
	w_value_h         *string
}

var (
	tagConfInfoData         map[string]*conf_table_define.TagInfo            //采集点表 key 为 tag_name
	transferTagConfInfoData map[string]map[string]*conf_table_define.TagInfo //转发点表 key 为 dev_id, vale  中 key 为 tag_name
	tagConfInfoTagIdToName  map[string]string                                //采集点表 映射表 key 为 tag_id value 为 tag_name
)

// 采集通道
func TagInfoList() map[string]*conf_table_define.TagInfo {
	return tagConfInfoData
}

func FindTagInfoByTagId(Tag_id string) *conf_table_define.TagInfo {
	if tag_name, ok := tagConfInfoTagIdToName[Tag_id]; ok {
		return tagConfInfoData[tag_name]
	}
	return nil
}

// 转发通道

func TransferTagInfoList() []*conf_table_define.TagInfo {
	result := make([]*conf_table_define.TagInfo, 0, 500)
	for _, tagsMap := range transferTagConfInfoData {
		if len(tagsMap) <= 0 {
			continue
		}
		for _, tg := range tagsMap {
			result = append(result, tg)
		}
	}
	return result
}
func FindTransferTagInfoByDevId(dev_Id string) map[string]*conf_table_define.TagInfo {
	m, ok := transferTagConfInfoData[dev_Id]
	if ok {
		return m
	}
	return nil
}

func FindTransferTagInfoByTagName(dev_id, tag_name string) *conf_table_define.TagInfo {
	m, ok := transferTagConfInfoData[dev_id]
	if ok {
		tag, ok := m[tag_name]
		if ok {
			return tag
		}
		return nil
	}
	return nil
}

func selectTagInfo(db *sql.DB) error {
	//查询tag info
	fields := strings.Join(tbTagInfoColumns, ",")

	selectSql := "select " + fields + " from tb_tag_info order by id asc"
	rows, err := db.Query(selectSql)
	if err != nil {
		return err
	}
	defer func() {
		err := rows.Close()
		if err != nil {
			logrus.Warn("行关闭失败")
			return
		}
	}()

	tagConfInfoData, transferTagConfInfoData, err = convertTagInfo(rows)

	//处理  tag_id 到 tag_name  映射
	tagConfInfoTagIdToName = make(map[string]string, len(tagConfInfoData))
	for _, info := range tagConfInfoData {
		tagConfInfoTagIdToName[info.Tag_id] = info.Tag_name
	}

	if err != nil {
		return err
	}
	//atomic.StorePointer(&tagInfoEntitySptr, unsafe.Pointer(&info))
	return nil
}

func convertTagInfo(rows *sql.Rows) (map[string]*conf_table_define.TagInfo, map[string]map[string]*conf_table_define.TagInfo, error) {
	err := rows.Err()
	if err != nil {
		return nil, nil, err
	}

	deviceConfInfos := DeviceConfInfoList()

	resultMap := make(map[string]*conf_table_define.TagInfo, 2000)
	transferResultMap := make(map[string]map[string]*conf_table_define.TagInfo, 20)

	for rows.Next() {
		entity := tagInfoEntity{}
		err := rows.Scan(
			&entity.id,
			&entity.tag_descYcxmkt,
			&entity.tag_reserve,
			&entity.tag_id,
			&entity.tag_name,
			&entity.tag_desc,
			&entity.tag_type,
			&entity.tag_RW,
			&entity.tag_init,
			&entity.tag_K,
			&entity.tag_B,
			&entity.collect_type,
			&entity.obj_addr,
			&entity.assist_param,
			&entity.tag_group,
			&entity.data_type,
			&entity.data_format,
			&entity.enable_trans,
			&entity.org_read_value,
			&entity.trans_value,
			&entity.enable_bit,
			&entity.start_bit,
			&entity.end_bit,
			&entity.dev_id,
			&entity.enable_alarm,
			&entity.hh_enable_alarm,
			&entity.h_enable_alarm,
			&entity.l_enable_alarm,
			&entity.ll_enable_alarm,
			&entity.hh_alarm_limit,
			&entity.h_alarm_limit,
			&entity.l_alarm_limit,
			&entity.ll_alarm_limit,
			&entity.hh_alarm_msg,
			&entity.h_alarm_msg,
			&entity.l_alarm_msg,
			&entity.ll_alarm_msg,
			&entity.alarm_dead_area,
			&entity.kg_change_mode,
			&entity.kg_alarm_msg,
			&entity.alarm_level,
			&entity.enable_his_save,
			&entity.his_save_type,
			&entity.his_save_interval,
			&entity.his_comp_perc,
			&entity.is_upload,
			&entity.pv_flag,
			&entity.tag_source,
			&entity.tag_unit,
			&entity.rev2,
			&entity.rev3,
			&entity.rev4,
			&entity.ori_tag_id,
			&entity.tag_id_f,
			&entity.tag_id_h,
			&entity.w_value_f,
			&entity.w_value_h)

		if err != nil {
			return nil, nil, err
		}
		//todo 默认值
		item := &conf_table_define.TagInfo{}

		if entity.id != nil {
			item.Id = *entity.id
		}
		if entity.tag_descYcxmkt != nil {
			item.Tag_descYcxmkt = *entity.tag_descYcxmkt
		}
		if entity.tag_id != nil {
			item.Tag_id = strings.TrimSpace(*entity.tag_id)
		}
		if entity.tag_name != nil {
			item.Tag_name = strings.TrimSpace(*entity.tag_name)
		}
		if entity.tag_reserve != nil {
			item.Tag_reserve = *entity.tag_reserve
		}
		if entity.tag_desc != nil {
			item.Tag_desc = strings.TrimSpace(*entity.tag_desc)
		}
		if entity.tag_type != nil {
			item.Tag_type = *entity.tag_type
		}
		if entity.tag_RW != nil {
			item.Tag_RW = *entity.tag_RW
		}
		if entity.tag_init != nil {
			item.Tag_init = *entity.tag_init
		}
		if entity.tag_K != nil {
			item.Tag_K = *entity.tag_K
		}
		if entity.tag_B != nil {
			item.Tag_B = *entity.tag_B
		}
		if entity.collect_type != nil {
			item.Collect_type = *entity.collect_type
		}
		if entity.obj_addr != nil {
			item.Obj_addr = strings.TrimSpace(*entity.obj_addr)
			item.Obj_addr_int, _ = strconv.ParseInt(item.Obj_addr, 10, 64)
		}
		if entity.assist_param != nil {
			item.Assist_param = *entity.assist_param
		}
		if entity.tag_group != nil {
			item.Tag_group = strings.TrimSpace(*entity.tag_group)
		}
		if entity.data_type != nil {
			item.Data_type = *entity.data_type
		}
		if entity.data_format != nil {
			item.Data_format = *entity.data_format
		}
		if entity.enable_trans != nil {
			item.Enable_trans = *entity.enable_trans
		}
		if entity.org_read_value != nil {
			item.Org_read_value = *entity.org_read_value
		}
		if entity.trans_value != nil {
			item.Trans_value = *entity.trans_value
		}
		if entity.enable_bit != nil {
			item.Enable_bit = *entity.enable_bit
		}
		if entity.start_bit != nil {
			item.Start_bit = *entity.start_bit
		}
		if entity.end_bit != nil {
			item.End_bit = *entity.end_bit
		}
		//if entity.dev_id != nil {
		//	item.Dev_id = *entity.dev_id
		//}
		if entity.enable_alarm != nil {
			item.Enable_alarm = *entity.enable_alarm
		}
		if entity.hh_enable_alarm != nil {
			item.Hh_enable_alarm = *entity.hh_enable_alarm
		}
		if entity.h_enable_alarm != nil {
			item.H_enable_alarm = *entity.h_enable_alarm
		}
		if entity.l_enable_alarm != nil {
			item.L_enable_alarm = *entity.l_enable_alarm
		}
		if entity.ll_enable_alarm != nil {
			item.Ll_enable_alarm = *entity.ll_enable_alarm
		}
		if entity.hh_alarm_limit != nil {
			item.Hh_alarm_limit = *entity.hh_alarm_limit
		}
		if entity.h_alarm_limit != nil {
			item.H_alarm_limit = *entity.h_alarm_limit
		}
		if entity.l_alarm_limit != nil {
			item.L_alarm_limit = *entity.l_alarm_limit
		}
		if entity.ll_alarm_limit != nil {
			item.Ll_alarm_limit = *entity.ll_alarm_limit
		}
		if entity.hh_alarm_msg != nil {
			item.Hh_alarm_msg = *entity.hh_alarm_msg
		}
		if entity.h_alarm_msg != nil {
			item.H_alarm_msg = *entity.h_alarm_msg
		}
		if entity.l_alarm_msg != nil {
			item.L_alarm_msg = *entity.l_alarm_msg
		}
		if entity.ll_alarm_msg != nil {
			item.Ll_alarm_msg = *entity.ll_alarm_msg
		}
		if entity.alarm_dead_area != nil {
			item.Alarm_dead_area = *entity.alarm_dead_area
		}
		if entity.kg_change_mode != nil {
			item.Kg_change_mode = *entity.kg_change_mode
		}
		if entity.kg_alarm_msg != nil {
			item.Kg_alarm_msg = *entity.kg_alarm_msg
		}
		if entity.alarm_level != nil {
			item.Alarm_level = *entity.alarm_level
		}
		if entity.enable_his_save != nil {
			item.Enable_his_save = *entity.enable_his_save
		}
		if entity.his_save_type != nil {
			item.His_save_type = *entity.his_save_type
		}
		if entity.his_save_interval != nil {
			item.His_save_interval = *entity.his_save_interval
		}
		if entity.his_comp_perc != nil {
			item.His_comp_perc = *entity.his_comp_perc
		}
		if entity.is_upload != nil {
			item.Is_upload = *entity.is_upload
		}
		if entity.pv_flag != nil {
			item.Pv_flag = *entity.pv_flag
		}
		if entity.tag_source != nil {
			item.Tag_source = *entity.tag_source
		}
		if entity.tag_unit != nil {
			item.Tag_unit = *entity.tag_unit
		}
		if entity.rev2 != nil {
			item.Rev2 = *entity.rev2
		}
		if entity.rev3 != nil {
			item.Rev3 = *entity.rev3
		}
		if entity.rev4 != nil {
			item.Rev4 = *entity.rev4
		}
		if entity.ori_tag_id != nil {
			item.Ori_tag_id = strconv.Itoa(*entity.ori_tag_id)
		}
		if entity.tag_id_f != nil {
			item.Tag_id_f = *entity.tag_id_f
		}
		if entity.tag_id_h != nil {
			item.Tag_id_h = *entity.tag_id_h
		}
		if entity.w_value_f != nil {
			item.W_value_f = *entity.w_value_f
		}
		if entity.w_value_h != nil {
			item.W_value_h = *entity.w_value_h
		}
		item.DeviceInfo = deviceConfInfos[*entity.dev_id]
		if item.DeviceInfo.ChannelInfo.IsTransfer() {
			tagMap := transferResultMap[item.DeviceInfo.Dev_id]
			if tagMap == nil {
				tagMap = make(map[string]*conf_table_define.TagInfo, 100)
				transferResultMap[item.DeviceInfo.Dev_id] = tagMap
			}
			tagMap[item.Tag_name] = item
		} else {
			resultMap[item.Tag_name] = item
		}
	}

	return resultMap, transferResultMap, nil
}
